<?php

namespace app\home\controller;

use app\admin\model\Spec;
use app\common\model\mysql\Address;
use app\common\model\mysql\OrderGoods;
use app\common\model\mysql\SpecGoods;

use Pingpp\Charge;
use Pingpp\Pingpp;
use chillerlan\QRCode\{QRCode,QROptions};
use think\Exception;
use think\facade\Cache;
use think\facade\View;

class Order extends Base
{
    public function create()
    {

        $userId = $this->userId;
        $address = Address::where('user_id',$userId)->field('id,is_default,consignee,area,address,phone')->select()->toArray();

        $cartSelected = Cache::store('redisCart')->sMembers(config('redis.cart_selected').$userId);

        $cartData = Cache::store('redisCart')->hMGet(config('redis.cart_user').$userId,$cartSelected);


        $newCartData = array_map(function ($v){
            return json_decode($v,true);
        },$cartData);

        //商品总数量
        $totalNumber = array_sum(array_column($newCartData,'number'));


        $totalPrice = 0;
        //获取所有spec规格商品Id
        $specGoodsIds = array_column($newCartData,'spec_goods_id');
        $specGoodsData = SpecGoods::with('goods')->select($specGoodsIds)->toArray();
        foreach ($specGoodsData as &$value){
            $number = $newCartData[$value['id']]['number'];
            $price = $value['goods_price'];
            $value['number'] = $number;
            //商品总价格
            $totalPrice +=$price*$number;

        }
        unset($value);







        //获取购物车sku商品
        return view('create',['address'=>$address,'cart_data'=>$specGoodsData,'total_number'=>$totalNumber,'total_price'=>$totalPrice]);
    }

    public function save()
    {
        //接收参数
        $params = input();
        $address = Address::field('consignee,address,phone,area')->find($params['address_id'])->toArray();
        //参数检测
        $validate = $this->validate($params, [
            'address_id' => 'require|integer|gt:0'
        ]);
        if($validate !== true){
            $this->error($validate);
        }
        //生成订单号
        $nodeId = rand(1,1023);#随机数
        $orderNum = \SnowFlake::getInstance()->setWorkId($nodeId)->nextId();

        //获取购物车数据
        $redisConnection = Cache::store('redisCart');
        $cartSelected = $redisConnection->sMembers(config('redis.cart_selected').$this->userId);
        $cartData = $redisConnection->hMGet(config('redis.cart_user').$this->userId,$cartSelected);

        $newCartData = array_map(function ($v){
            return json_decode($v,true);
        },$cartData);


        //商品总数量
        $totalNumber = array_sum(array_column($newCartData,'number'));

        $totalPrice = 0;
        //获取商品的总价格
        $skuPrice = SpecGoods::field('id,price')->select(array_keys($newCartData))->toArray();
        foreach ($skuPrice as $value){
            $number = $newCartData[$value['id']]['number'];
            $price = $value['price'];
            $totalPrice +=$price*$number;
        }




//        unset($value);

        $order_data = [
            'user_id' => $this->userId,
            'order_sn' => $orderNum,
            'consignee' => $address['consignee'],
            'address' => $address['area'] . $address['address'],
            'phone' => $address['phone'],
            'goods_price' => $totalPrice, //商品总价
            'shipping_price' => 0,//邮费
            'coupon_price' => 0,//优惠金额
            'order_amount' => $totalPrice,//应付金额=商品总价+邮费-优惠金额
            'total_amount' => $totalPrice,//订单总金额=商品总价+邮费
        ];
        $orderModel = new \app\common\model\mysql\Order();

        $orderModel->startTrans();
        try {
            //添加订单表
            $orderModel->save($order_data);
            $orderId = $orderModel->id;

            //向订单商品表添加多条数据
            $order_goods_data = [];
            $specGoodsData = SpecGoods::with('goods')->select(array_keys($newCartData))->toArray();
//            halt($specGoodsData);
            foreach ($specGoodsData as $v){
                $row = [
                    'order_id' => $orderId,
                    'goods_id' => $v['goods_id'],
                    'spec_goods_id' => $v['id'],
                    'number' => $newCartData[$v['id']]['number'],
                    'goods_name' => $v['goods_name'],
                    'goods_logo' => $v['goods_logo'],
                    'goods_price' => $v['goods_price'],
                    'spec_value_names' => $v['value_names'],
                ];
                $order_goods_data[] = $row;
            }
            //批量添加
            $model = new OrderGoods();
            $model->saveAll($order_goods_data);


            //更新sku库存表

            foreach($newCartData as $value)
            {

                SpecGoods::where('id',$value['spec_goods_id'])->dec('store_count',$value['number'])->update();
            }
            //删除购物车
            $redisConnection->multi();
            foreach ($newCartData as $k=>$v){
                $redisConnection->hDel(config('redis.cart_user').$this->userId,$k);
                $redisConnection->sRem(config('redis.cart_selected').$this->userId,$k);
            }

            //购物车添加redis zSet
            // 把当前订单ID 放入延迟队列中， 定期检测订单是否已经支付 （因为订单有效期是20分钟，超过这个时间还没有支付的，
            // 我们需要把这个订单取消 ， 然后库存+操作）小伙伴需要举一反三，比如其他场景也可以用到延迟队列：发货提醒等
            // 学习就是要不断的提升自己，老师授的只是思路，我们需要举一反三，从而提升自己

            $redisConnection->zAdd(config("redis.order_status_key"), time() + config("redis.order_expire"), $orderId);


            $redisConnection->exec();

            //*聚合支付 开始*/
            //二维码图片中的支付链接（本地项目自定义链接，传递订单id参数）
            //$url = url('/home/order/qrpay', ['id'=>$order->order_sn], true, true);
            //用于测试的线上项目域名 http://pyg.tbyue.com
            $url = url('/home/order/qrpay', ['id'=>$orderNum, 'debug'=>'true'], true, config('pay.qrUrl'));
            //生成支付二维码
//            $options = new QROptions([
//               'version' => 4,  //二维码版本
//               'outputType' => QRCode::OUTPUT_IMAGE_PNG, //生成图片
//                'eccLevel'  => QRCode::ECC_H,                 //错误级别
//                'scale'=>10,                                   //二维码大小
//            ]);
            $qrCode = new QRCode();
            //二维码图片保存路径
            $qr_path = '/uploads/qrcode/'.uniqid(mt_rand(100000,999999), true).'.png';
            //将二维码图片信息保存到文件中
            $qrCode->render($url,'.'.$qr_path);
            View::assign('qr_path', $qr_path);
            $orderModel->commit();
        }catch (Exception $e){
            var_dump($e->getMessage());
            $orderModel->callBack();

        }
        return view('pay',['order_sn' => $orderNum, 'pay_type'=>config('pay.pay_type'), 'total_price'=>$totalPrice]);
    }


    /**
     * 去支付
     */
    public function pay()
    {
        //接收参数
        $params = input();
        //检测参数
        $validate = $this->validate($params, [
            'order_sn' => 'require',
            'pay_code|支付方式' => 'require'
        ]);
        if($validate !== true){
            $this->error($validate);
        }
        //查询订单
        $user_id = session('user_info.id');
        $order =\app\common\model\mysql\Order::where('order_sn', $params['order_sn'])->where('user_id', $user_id)->find();
        if(!$order){
            $this->error('订单不存在');
        }
        //将选择的支付方式，修改到订单表
        $pay_type = config('pay_type');
        $order->pay_code = $params['pay_code'];
        //$order->pay_name = config('pay_type.' . $params['pay_code'])['pay_name'];
        $order->pay_name = $pay_type[$params['pay_code']]['pay_name'];
        $order->save();
        //支付（根据支付方式进行处理）
        switch ($params['pay_code']){
            case 'wechat':
                //微信支付
                break;
            case 'union':
                //银联支付
                break;
            case 'alipay':
                //支付宝
            default:
                //默认 支付宝
                break;
        }
    }
    //后面的是聚合支付相关方法
    public function qrpay()
    {
        //判断支付方式
        $agent = request()->server('HTTP_USER_AGENT');
        //判断扫码支付方式
        if(strpos($agent,'MicroMessenger') !== false){
            //微信扫码
            $pay_code = 'wx_pub_qr';
        }else if(strpos($agent,'AlipayClient') !== false){
            //支付宝扫码
            $pay_code = 'alipay_qr';
        }else{
            //默认为支付宝扫码支付
            $pay_code = 'alipay_qr';
        }
        //基本步骤
        //接受参数 订单编号
        //查询订单信息
        //创建支付请求 向ping++发送请求
        //跳转支付页面
        //接受订单id参数
        $order_sn = input('id');
        //创建支付请求
        $this->pingpp($order_sn,$pay_code);

    }

    public function pingpp($order_sn,$pay_code)
    {
        //查询订单信息
        $order = \app\common\model\mysql\Order::where('order_sn',$order_sn)->find();
        //ping++聚合支付
        Pingpp::setApiKey(config('pingpp.api_key'));//设置api key
        Pingpp::setPrivateKeyPath(config('pingpp.private_key_path'));//设置私钥
        Pingpp::setAppId(config('pingpp.app_id'));
        $params = [
            'order_no'  => $order['order_sn'],
            'app'       => ['id' => config('pingpp.app_id')],
            'channel'   => $pay_code,
            'amount'    => $order['order_amount'],
            'client_ip' => '127.0.0.1',
            'currency'  => 'cny',
            'subject'   => 'Your Subject',//自定义标题
            'body'      => 'Your Body',//自定义内容
            'extra'     => [],
        ];
        if($pay_code == 'wx_pub_qr'){
            $params['extra']['product_id'] = $order['id'];
        }
        //创建charge对象
        $ch = Charge::create($params);
        //跳转到对应第三方支付链接
        return redirect($ch->credential->$pay_code);
    }

    //查询支付状态
    public function status()
    {
        //接受订单编号
        $order_sn = input('order_sn');
        $order_status = \app\common\model\mysql\Order::where('order_sn', $order_sn)->value('order_status');
        return json(['code' => 200, 'msg' => 'success', 'data'=>$order_status]);
        //通过线上测试
//        $res = curl_request("http://pyg.tbyue.com/home/order/status/order_sn/{$order_sn}");
//        echo $res;die;

    }

    /**
     * 支付结果页面
     */
    public function payresult()
    {
        $order_sn = input('order_sn');
        $order = \app\common\model\mysql\Order::where('order_sn',$order_sn)->find();
        if(empty($order)){
            return view('payfail',['msg'=>'订单编号错误']);
        }else{
            return view('paysuccess', ['pay_name' => $order->pay_name, 'order_amount'=>$order['order_amount'], 'order' => $order]);

        }

    }

    /**
     * 页面跳转 同步通知地址
     */
    public function callback(){
        $params = input();
        //参数检测（签名验证）  接收到的参数 和 支付宝传递的参数 是否发生改变
        require_once("./plugins/alipay/config.php");
        require_once("./plugins/alipay/pagepay/service/AlipayTradeService.php");

        $alipaySevice = new \AlipayTradeService($config);
        $result = $alipaySevice->check($params);
        if($result){
            //验签成功
            $order_sn = $params['out_trade_no'];
            $order = \app\common\model\mysql\Order::where('order_sn', $order_sn)->find();
            //展示结果
            return view('paysuccess', ['pay_name' => '支付宝', 'order_amount'=>$params['total_amount'], 'order' => $order]);
        }else{
            //验签失败
            //展示结果
            return view('payfail', ['msg' => '支付失败']);
        }
    }


}